package com.burgeon.backend.SHOP.controller;


import com.burgeon.backend.SHOP.entity.*;
import com.burgeon.backend.SHOP.entity.presell.Earnest;
import com.burgeon.backend.SHOP.mappers.AppPresellMapper;
import com.burgeon.backend.SHOP.mappers.BargainMapper;
import com.burgeon.backend.SHOP.mappers.PlusActiveMapper;
import com.burgeon.backend.SHOP.rest.Submit;
import com.burgeon.backend.SHOP.rest.recharger.FindRECHARGEByXSDH;
import com.burgeon.backend.SHOP.service.*;
import com.burgeon.backend.SHOP.wechat.Util.WXPayUtil;
import com.burgeon.backend.SHOPBACKEND.entity.ShopKf;
import com.burgeon.backend.SHOPBACKEND.mappers.WeChatKfMapper;
import com.burgeon.backend.SHOPBACKEND.service.BackendCouponGiftService;
import com.burgeon.backend.entity.Info;
import com.burgeon.backend.mappers.AccountMapper;
import com.burgeon.backend.service.QueueService;
import com.burgeon.backend.service.UserService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("shop/pay")
public class PayController extends BaseController {

    private final static Log logger = LogFactory.getLog(PayController.class);
    private final static String PAYOK =
            "<xml><return_code><![CDATA[SUCCESS]]></return_code>" +
                    "<return_msg><![CDATA[OK]]></return_msg></xml>";

    @Autowired
    private PayWechatService payWechatService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private EmpNotificationMessageService empNotificationMessageService;
    @Autowired
    private WeChatKfMapper weChatKfMapper;
    @Autowired
    private BargainMapper bargainMapper;
    @Autowired
    private AppPresellService appPresellService;
    @Autowired
    private AppPresellMapper appPresellMapper;
    @Autowired
    private QueueService queueService;
    @Autowired
    private PlusActiveService plusActiveService;
    @Autowired
    private UserService userService;
    @Autowired
    private PlusActiveMapper plusActiveMapper;
    @Autowired
    private BackendCouponGiftService backendCouponGiftService;


    /**
     * 用于接收支付回调
     *
     * @param code
     * @param response
     */
    @RequestMapping("recharge/{token}")
    public void rechargeResult(@RequestBody String code, @PathVariable("token") String token, HttpServletResponse response) {

        System.err.println("code" + code);
        try {
            wxpayCallbackResult(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String, String> data = new HashMap<>();
        try {
            data = WXPayUtil.xmlToMap(code);
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        //根据订单号 查询存入的会员订单信息  获取用户id
        String returnCode = data.get("return_code");
        String outTradeNo = data.get("out_trade_no");
        String resultCode = data.get("result_code");
        String errCodeDes = data.get("err_code_des");

        System.err.println(returnCode);


        if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
            Info info = GetInfo(token);
            FindRECHARGEByXSDH findRECHARGEByXSDH = new FindRECHARGEByXSDH(info.getUrl(), info.getAccount(), info.getPassword());

            Submit submit = new Submit(info.getUrl(), info.getAccount(), info.getPassword());
            //修改状态
            try {
                Recharge recharge = findRECHARGEByXSDH.getData(outTradeNo);
                if (null != recharge.getId()) {
                    String icode = submit.getData(recharge.getId(), "YC_VIPMONEY");//提交预售定金

                }
            } catch (Exception e) {
                logger.error(e.getMessage());

                e.printStackTrace();
            }


        }
    }

    /**
     * plus会员
     * 用于接收支付回调
     */

    @RequestMapping("plusResult/{token}")
    public void plusResult(@RequestBody String code, @PathVariable("token") String token, HttpServletResponse response) {

        System.err.println("code" + code);
        try {
            wxpayCallbackResult(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String, String> data = new HashMap<>();
        try {
            data = WXPayUtil.xmlToMap(code);
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        String returnCode = data.get("return_code");
        String outTradeNo = data.get("out_trade_no");
        String resultCode = data.get("result_code");
        /*String errCodeDes = data.get("err_code_des");*/

        System.err.println(returnCode);

        if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
            String uid = plusActiveService.findUid(outTradeNo);
            /*PlusApplyRecord plusApplyRecordOperation = plusActiveService.findOperation(uid, token);*/
            PlusApplyRecord plusApplyRecord = plusActiveService.findState(uid, token);
            if (plusApplyRecord!=null) {
                plusActiveService.upEndDate(outTradeNo, token,plusApplyRecord.getEndDate());//续费
            } else {
                plusActiveService.upState(outTradeNo, token);//开通
                String phone = userService.findPhone(uid,token);//获取开通人电话
                PlusActiveConfiguration plusActiveConfiguration = plusActiveMapper.findInfo(token);//获取每月神券、无门槛券ID

                //发券
                backendCouponGiftService.createCoupon(plusActiveConfiguration.getMonthCouponGiftId().toString(),phone,token);//发送每月神券
                backendCouponGiftService.createCoupon(plusActiveConfiguration.getThresholdCouponGiftId().toString(),phone,token);//发送无门槛券

                PlusSendRecord plusSendRecord = new PlusSendRecord();
                plusSendRecord.setUid(uid);
                plusSendRecord.setToken(token);
                plusActiveMapper.addPlusSendRecord(plusSendRecord);//新增发送记录
            }
            plusActiveService.upUserIsPlus(uid, token);//修改为Plus会员
        }

    }


    /**
     * 用于接收支付回调
     *
     * @param code
     * @param response
     */
    @RequestMapping("earnest")
    public void earnestResult(@RequestBody String code, HttpServletResponse response) {

        System.err.println("code" + code);
        try {
            wxpayCallbackResult(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String, String> data = new HashMap<>();
        try {
            data = WXPayUtil.xmlToMap(code);
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        //根据订单号 查询存入的会员订单信息  获取用户id
        String returnCode = data.get("return_code");
        String outTradeNo = data.get("out_trade_no");
        String resultCode = data.get("result_code");
        String errCodeDes = data.get("err_code_des");

        System.err.println(returnCode);


        if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
            Earnest earnest = appPresellService.getEarnestDataByCode(outTradeNo);

            Info info = GetInfo(earnest.getToken());
            Submit submit = new Submit(info.getUrl(), info.getAccount(), info.getPassword());
            //修改状态
            try {
                if (null != earnest.getErpId()) {
                    String icode = submit.getData(earnest.getErpId(), "YC_YSRETAIL");//提交预售定金
                    earnest.setErpId(icode);
                }
            } catch (Exception e) {
                logger.error(e.getMessage());

                e.printStackTrace();
            }
            appPresellService.upEarnestState(earnest.getId(), earnest.getErpId(), "Y");

        }
    }

    /**
     * 用于接收退款回调
     *
     * @param code
     * @param response
     */
    @RequestMapping("refundResult")
    public void refundResult(@RequestBody String code, HttpServletResponse response) {
        System.err.println("code" + code);
        try {
            wxpayCallbackResult(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String, String> data = new HashMap<>();
        try {
            data = WXPayUtil.xmlToMap(code);
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        String returnCode = data.get("return_code");
        String outTradeNo = data.get("out_trade_no");
        String resultCode = data.get("result_code");
        String errCodeDes = data.get("err_code_des");
        String reqInfo = data.get("req_info");
        System.err.println(returnCode);

        // System.err.println(decryptData(reqInfo));


    }

    /**
     * 用于接收支付回调
     *
     * @param code
     * @param response
     */
    @RequestMapping("result")
    public void Result(@RequestBody String code, HttpServletResponse response) {

        System.err.println("code" + code);
        try {
            wxpayCallbackResult(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String, String> data = new HashMap<>();
        try {
            data = WXPayUtil.xmlToMap(code);
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        //根据订单号 查询存入的会员订单信息  获取用户id
        String returnCode = data.get("return_code");
        String outTradeNo = data.get("out_trade_no");
        String resultCode = data.get("result_code");
        String errCodeDes = data.get("err_code_des");

        System.err.println(returnCode);
        //判断成功 修改对应订单状态为1 已支付 写入修改时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String now = sdf.format(date);

        if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
            orderService.UpOrderState(outTradeNo, "1", now);
            Order order = orderService.FindOrderByCode(outTradeNo);
            //预售定金单状态
            try {
                if ("Y".equals(outTradeNo.substring(outTradeNo.length() - 1))) {
                    System.err.println("预售单");
                    appPresellMapper.upPresellState(order.getId(), "S");

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            //砍价单状态
            try {
                bargainMapper.upBargainStateByOid(order.getId(), "3");
            } catch (Exception e) {
                e.printStackTrace();
            }

            Info info = GetInfo(order.getToken());
            Submit submit = new Submit(info.getUrl(), info.getAccount(), info.getPassword());

            try {
                if (null != order.getIntegralCode()) {
                    String icode = submit.getData(order.getIntegralCode(), "WX_VIPINTEGRALADJ");//提交积分调整单
                    order.setIntegralCode(icode);
                }

            } catch (Exception e) {
                logger.error(e.getMessage());
                order.setIntegralMessage(e.getMessage());
                e.printStackTrace();
            }


            try {
                if (null != order.getRetailCode()) {
                    String rcode = submit.getData(order.getRetailCode(), "YC_RETAIL");//提交零售单
                    order.setRetailCode(rcode);
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
                order.setRetailMessage(e.getMessage());
                e.printStackTrace();
            }
            orderService.UpERPData(order);
//发送客服消息********************************************************
            //企业微信新订单通知
            queueService.sendEWEmpNewOrder(order.getUid(),order.getRetailCode(),order.getToken());
            try {
                //获取订单信息 会员电话 会员名 推送的客服名称 订单号 token
                //获取要发送的openid
                ArrayList<ShopKf> shopKfs = weChatKfMapper.getKf(order.getToken());
                //判断发送订单消息/积分兑换消息
                for (ShopKf shopKf : shopKfs) {
                    if (Integer.parseInt(order.getTotalIntegral()) > 0) {
                        //积分兑换
                        empNotificationMessageService.sendEmpCreditsExchange("客服", order.getName(), order.getPhone(),
                                shopKf.getOpenid(), order.getRetailCode(), order.getToken());
                    } else {
                        empNotificationMessageService.sendEmpNewOrder(
                                "客服", order.getName(), order.getPhone(),
                                shopKf.getOpenid(), order.getRetailCode(), order.getToken());
                    }
                }

            } catch (Exception e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }
        }
    }

    /*@RequestMapping("send")
    public ResponseResult<PayData> GetIndexImg(HttpSession session) {

        String token = session.getAttribute("token").toString();
        String openid = session.getAttribute("app_openid").toString();
        PayData data = payWechatService.createUnified(openid, token, WXPayUtil.generateNonceStr() + "", "1", "测试");

        return new ResponseResult<PayData>(SUCCESS, data);
    }*/

    private void wxpayCallbackResult(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/xml; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print(PayController.PAYOK);
        out.close();
    }

    private Info GetInfo(String token) {
        return accountMapper.GetTokenData(token);
    }


    /**
     * 密钥算法
     */
    private static final String ALGORITHM = "AES";
    /**
     * 加解密算法
     */
    private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS5Padding";


    private static byte[] decode(String key) throws Exception {

        return new BASE64Decoder().decodeBuffer(key);

    }


    private static String decryptData(String base64Data) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
        cipher.init(Cipher.DECRYPT_MODE,
                new SecretKeySpec(WXPayUtil.MD5("Sm73MYZMk7AQtJ89ArZrDUYQLqAHhSwj")
                        .toLowerCase().getBytes(), "AES"));
        return new String(cipher.doFinal(decode(base64Data)), StandardCharsets.UTF_8);
    }


}
